/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						       combat_spell.h

	$Header: /game/combat_spell.h $

	$NoKeywords: $

 ************************************************************************/

#ifndef COMBAT_SPELL_H_INCLUDED
#define COMBAT_SPELL_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <string>
#include "combat_ai_action_ptr.h"
#include "combat_creature_ptr.h"
#include "combat_spell_ptr.h"


class  t_artifact;
enum   t_artifact_slot;
enum   t_artifact_type;
class  t_battlefield;
class  t_combat_ai;
class  t_combat_creature;
struct t_map_point_2d;
class  t_mouse_window;
struct t_screen_point;
enum   t_spell;

// ------------------------------------------------------------------
// base class for combat spellcasting handlers
// ------------------------------------------------------------------
class t_combat_spell : public t_counted_object
{
public:
	t_combat_spell( t_battlefield& battlefield, t_spell spell );

	virtual void			ai_cast_spell();
	virtual double          ai_weight( t_combat_creature const& target) const;
	virtual bool            begin_casting() = 0;
	virtual bool		    can_cast( t_screen_point const& point ) const;
	virtual bool			can_cast_on( t_combat_creature* creature, 
		                                 std::string*       help_text ) const;
	virtual bool            cast_on( t_combat_creature_ptr	caster, 
		                             t_combat_creature_ptr	target, 
									 int power,
									 bool is_mirror ); // execute
	virtual void			cast_and_mirror( t_combat_creature_ptr target, int power ); // execute and mirror
	virtual void            execute( t_combat_creature& caster ) = 0;
	virtual void            execute_mirror_spell( t_combat_creature_ptr creature, int power );
	virtual t_combat_ai_action_list generate_combat_ai_action_list(t_combat_ai &owner) = 0;
	std::string				get_action_text( bool is_mirror ) const;
	std::string				get_artifact_name() const;
	t_artifact_type         get_artifact_type() const;
	virtual double			get_cancel_weight( t_combat_creature const& target ) const = 0;
	t_spell					get_cast_spell() const;
	t_combat_creature_ptr   get_caster() const;
	t_spell                 get_spell_type() const;
	bool					is_potion() const;
	virtual t_mouse_window* mouse_move( t_screen_point const& point,
									    std::string& help_text );
	void					play_sound() const;
	virtual void			left_button_down( t_screen_point const& screen_point );
	virtual bool            left_click( t_screen_point const& point );
	void					set_artifact( t_artifact_slot slot, int backpack_slot );
	void					set_cast_spell( t_spell spell );
	void					set_caster( t_combat_creature_ptr creature );
	void                    set_spell( t_spell spell );


	// Durations for combat spells
	enum
	{
		k_duration_blind = 3,
		k_duration_confusion = 1,
		k_duration_cowardice = 3,
		k_duration_frozen = 2,
		k_duration_hypnotize = 3,
		k_duration_quickness = 2,
		k_duration_short_hypnotism = 1,
		k_duration_song_of_peace = 1,
		k_duration_stun = 1,
		k_duration_summon_stinkbug = 1,
		k_duration_terror = 2
	};

protected:
	void pay_cost();

	std::string				m_artifact_name;
	t_artifact_slot			m_artifact_slot;
	t_artifact_type			m_artifact_type;
	int						m_backpack_slot;
	t_battlefield&			m_battlefield;
	t_spell					m_cast_spell; // The spell that was actually selected by the user, for display purposes ONLY
	t_combat_creature_ptr	m_caster;
	bool					m_is_artifact;
	t_spell					m_spell;
};

inline std::string t_combat_spell::get_artifact_name() const
{
	return m_artifact_name;
}

inline t_artifact_type t_combat_spell::get_artifact_type() const
{
	return m_artifact_type;
}

inline t_spell t_combat_spell::get_cast_spell() const
{
	return m_cast_spell;
}

inline t_combat_creature_ptr t_combat_spell::get_caster() const
{
	return m_caster;
}

inline t_spell t_combat_spell::get_spell_type() const
{
	return m_spell;
}

inline bool t_combat_spell::is_potion() const
{
	return m_is_artifact && m_backpack_slot >= 0;
}

inline void t_combat_spell::set_cast_spell( t_spell spell )
{
	m_cast_spell = spell;
}

inline void t_combat_spell::set_caster( t_combat_creature_ptr creature )
{
	m_caster = creature;
}

inline void t_combat_spell::set_spell( t_spell spell )
{
	m_spell = spell;
	m_cast_spell = spell;
}

#endif // COMBAT_SPELL_H_INCLUDED